package org.fuxia.im.core.socket;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Inet4Address;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
import java.util.TimerTask;

import org.apache.log4j.Logger;

/**
 * 用于传输文件的Socket
 * 
 * @author Fuxia
 * 
 */
public class FileTransferScoketServer implements Runnable
{
	private static final Logger	logger	= Logger.getLogger(FileTransferScoketServer.class);
	private static final Random	RANDOM	= new Random();
	private int					port	= -1;
	private ServerSocket		server;
	private String				ipAddress;
	private volatile boolean				isCreated;
	private File				newFile;
	private FileTransferCallBack callBack;
	private Long 				timeout = 10 * 60 * 1000L ;
	private volatile boolean clientConnected ;

	private FileTransferScoketServer(int port) throws Exception
	{
		if (port == -1)
		{
			port = RANDOM.nextInt(65534 - 1024) + 1024;
		}
		try
		{
			server = new ServerSocket(port, Integer.MAX_VALUE, Inet4Address.getLocalHost());
			
			/**
			 * 指定服务器在timeout时间之后还没收到信息则关闭
			 */
			new java.util.Timer().schedule(new TimerTask() {
				@Override
				public void run() {
					if(!clientConnected) {
						shutdown();
						try {
							getServer().close();
						} catch (IOException e) {
							//e.printStackTrace();
						}
					}
				}
			}, timeout);
			this.port = port;
			isCreated = true;
			this.ipAddress = server.getInetAddress().getHostAddress();
		}
		catch (Exception e)
		{
			throw e;
		}

	}

	/**
	 * 创建文件传输服务器
	 * 
	 * @return
	 * @throws IOException
	 */
	public static FileTransferScoketServer newInstance() throws Exception
	{
		return new FileTransferScoketServer(-1);
	}

	/**
	 * 根据指定的端口号，创建文件传输服务器
	 * 
	 * @param port
	 * @return
	 * @throws IOException
	 */
	public static FileTransferScoketServer newInstance(final int port) throws Exception
	{
		return new FileTransferScoketServer(port);
	}

	public void run()
	{
		logger.info("文件传输服务器已经启动");
		while (isCreated)
		{
			try
			{

				Socket client = server.accept();
				clientConnected = true ;
				InputStream is = client.getInputStream();
				long count = 0;
				byte[] buffer = new byte[1024];
				FileOutputStream fos = new FileOutputStream(newFile);
				while (is.read(buffer) != -1)
				{
					count += buffer.length;
					fos.write(buffer);
					callBack.callBack(count);
				}
				is.close();
				callBack.callBack("end");
			}
			catch (IOException e)
			{
			}
		}
	}

	public int getPort()
	{
		return this.port;
	}

	public String getIpAddress()
	{
		return this.ipAddress;
	}

	public void setFile(File file)
	{
		this.newFile = file;
	}

	public FileTransferCallBack getCallBack() {
		return callBack;
	}

	public void setCallBack(FileTransferCallBack callBack) {
		this.callBack = callBack;
	}

	public void shutdown() {
		try {
			logger.info("文件传输服务器关闭成功");
			this.server.close();
			isCreated = false;
		} catch (IOException e) {
			// non - ops
		}
	}

	public Long getTimeout() {
		return timeout;
	}

	public void setTimeout(Long timeout) {
		this.timeout = timeout;
	}

	public boolean isCreated() {
		return isCreated;
	}

	public void setCreated(boolean isCreated) {
		this.isCreated = isCreated;
	}

	public ServerSocket getServer() {
		return server;
	}

	public void setServer(ServerSocket server) {
		this.server = server;
	}
}
